package com.demo.controller;

/**
 * @Author DongXL
 * @Create 2017-01-05 19:40
 */

import com.demo.uitls.SpringContextHolder;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import freemarker.template.Template;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.servlet.view.AbstractView;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.Map;


public abstract class AbstractPdfView extends AbstractView {

    public AbstractPdfView() {
        this.setContentType("application/pdf");
    }

    @Override
    protected boolean generatesDownloadContent() {
        return true;
    }

    @Override
    protected final void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
        ByteArrayOutputStream baos = this.createTemporaryOutputStream();
        Document document = this.newDocument();
        PdfWriter writer = this.newWriter(document, baos);
        this.prepareWriter(model, writer, request);
        this.buildPdfMetadata(model, document, request);
        document.open();
        this.buildPdfDocument(model, document, writer, request, response);
        document.close();
        this.writeToResponse(response, baos);
    }

    protected Document newDocument() {
        return new Document(PageSize.A4);
    }

    protected PdfWriter newWriter(Document document, OutputStream os) throws DocumentException {
        return PdfWriter.getInstance(document, os);
    }

    protected void prepareWriter(Map<String, Object> model, PdfWriter writer, HttpServletRequest request) throws DocumentException {
        writer.setViewerPreferences(this.getViewerPreferences());
    }

    protected int getViewerPreferences() {
        return 2053;
    }

    protected void buildPdfMetadata(Map<String, Object> model, Document document, HttpServletRequest request) {
    }

    public abstract String fetchViewName();

    protected void buildPdfDocument(Map<String, Object> map, Document document, PdfWriter pdfWriter, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        Template tpl = getFtlTemplate(fetchViewName());
        String content = FreeMarkerTemplateUtils.processTemplateIntoString(tpl, map);
        XMLWorkerHelper.getInstance().parseXHtml(pdfWriter, document, new ByteArrayInputStream(content.getBytes()), Charset.forName("UTF-8"));
    }

    private Template getFtlTemplate(String fileName) throws IOException {
        FreeMarkerConfigurer freemarkerConfig = SpringContextHolder.INSTANCE.getBean(FreeMarkerConfigurer.class);
        return freemarkerConfig.getConfiguration().getTemplate(fileName + ".ftl");
    }
}
